<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // var obj = {
    //     x: 1,
    //     y: 2

    // }
    // var obj2 = {
    //     'x': 11,
    //     'y': 12,
    // }





    // 工厂模式
    // function createPerson(x, y, obj) {
    //     let o = new Object();
    //     o.x = x;
    //     o.y = y;
    //     o.obj = obj;
    //     o.sayName = function () {
    //         console.log(this.name);
    //     }
    //     return o;

    // }
    // let person1 = createPerson('NiNi', 20, 'sososo');

    // let person2 = createPerson('GIGI', 20, 'hehehe');
    // console.log(person1, person2);





    // 构造函数
    // function Person(a, b, d) {
    //     this.a = a;
    //     this.b = b;
    //     this.d = d;
    //     this.sayName = function () {
    //         console.log(this.a);
    //     }

    // }
    // var person1 = new Person('NiNi', 20, 'sososo');
    // var person2 = new Person('GIGI', 20, 'hehehe');
    // person1.sayName();
    // person2.sayName();

    //判断对象的构造函数与本身的构造函数是否相等
    // console.log(person1.constructor == Person); //true
    // console.log(person2 instanceof Person); //true




    // 构造函数的问题
    // 对象的方法写在构造函数的内部，每次实例化的时候都会重新创建这个方法，浪费内存和性能，为了解决，可以把方法定在构造函数外面，放置在对象的原型上
    // function Person(a, b, d) {
    //     this.a = a;
    //     this.b = b;
    //     this.d = d;
    //     // this.sayName = function () {
    //     //     console.log(this.a);
    //     // }
    // }
    // Person.prototype.sayName = function () {
    //     console.log(this.a);
    // }
    // var person1 = new Person('NiNi', 20, 'sososo');
    // var person2 = new Person('GIGI', 20, 'hehehe');
    // person1.sayName();
    // person2.sayName();




    // 原型模式:把对象所有的属性和方法都挂在原型上
    // function Person() {
    // }
    // Person.prototype.name = 'Tom';
    // Person.prototype.age = '18';
    // Person.prototype.sex = '男';
    // Person.prototype.sayName = function () {
    //     console.log(this.name);
    // }
    // var person1 = new Person();
    // var person2 = new Person();
    // person1.sayName();
    // person2.sayName();



    // 动态原型模式
    // function Person() {
    // }
    // Person.prototype.getName = function () {
    //     return this.name;
    // }
    // Person.prototype.setName = function (newName) {
    //     this.name = newName;
    // }
    // var person1 = new Person();
    // var person2 = new Person();
    // person1.setName('张三');
    // person2.setName('李四');
    // console.log(person1.getName());
    // console.log(person2.getName());



    // Object.create方法创建对象
    // var obj = {
    //     x: 1,
    //     y: 2
    // }
    // console.log(obj);
    // // 使用create方法实现给声明的的对象指定原型对象
    // var newObj = Object.create(obj);
    // newObj.x = 10;
    // newObj.y = 11;
    // console.log(newObj);
    // // 创建一个单纯的对象
    // var nullObj = Object.create(null);
    // console.log(nullObj);





    // 浅拷贝
    // var person1 = {
    //     name: '张三',
    //     age: 20,
    //     city: ['陕西', '西安'],
    //     sayName: function () {
    //         console.log(this.name);
    //     }
    // }
    // var a = person1;
    // a.name = '李四';
    // a.age = 19;
    // console.log(person1.name); //李四
    // console.log(a.name);//李四
    // // 深拷贝
    // var newObj = JSON.parse(JSON.stringify(person1));
    // a.name = '王五';
    // console.log(a.name);//王五
    // console.log(newObj.name);//李四






    // 对象的循环遍历
    // var obj = {
    //     name: 'lili',
    //     age: 18,
    //     sex: '女',
    // }
    // Object.defineProperty(obj, 'hobby', {
    //     value: '羽毛球',
    //     enumerable: true//是否可枚举，能否被循环到，默认是true
    // });
    // for (item in obj) {
    //     console.log(item);
    // }
    // // 遍历每一个键，返回一个数组包含所有键名
    // console.log(Object.keys(obj));
    // // 遍历每一个值，返回一个数组包含所有键值
    // console.log(Object.values(obj));
    // // 遍历每一个键值对，返回一个数组包含所有键值对
    // console.log(Object.entries(obj));






    // delete运算符删除对象的属性
    // var obj = {
    //     a: 'aaa',
    //     b: 'bbb',
    //     c: 'ccc',
    // }
    // console.log(obj);
    // delete obj.b;
    // console.log(obj);
    // 面试题:使用delete运算符删除数组中的某一个元素，结果会怎么样？？
    // 删除数组中的某一个元素，结果只是改变了这个元素的值，数组的长度不会被改变
    // var arr = [1, 2, 3, 4, 5];
    // delete arr[3];
    // console.log(arr);
    // 还可以通过解构赋值的方法来达到删除效果
    // const { a, b, ...obj } = obj;
    // console.log(obj);





    // in运算符检测对象的属性
    // var obj = {
    //     name: 'Tom',
    //     age: 18
    // }
    // console.log('name' in obj); //true
    // // hasOwnProperty()方法作用是判断对象本身是否存在某属性
    // console.log(obj.hasOwnProperty('name')); //true




    // get：获取 set：设置
    // var obj = {
    //     a: 1,
    // }
    // Object.defineProperty(obj, 'a', {
    //     enubmerable: true,//是否可枚举
    //     writablre: true,//是否可修改
    //     configurable: true,//是否可配置
    //     get: function () {
    //         // 获取指定属性值
    //         return 3
    //     }, set: function () {
    //         // 设置指定属性值
    //         console.log('修改了a的属性');
    //     },
    //
    //
    //     // es6
    //     // get() {
    //     //     // 获取指定属性值
    //     //     return 3
    //     // }, set() {
    //     //     // 设置指定属性值
    //     // },
    // })
    // obj.a = 2;
    // console.log(obj.a)//3
    // // 面试题:如何实现一个方法，让a.b ==2
    // var a = {
    //     b: 1,
    //     c: {
    //         d: 3
    //     }
    // }
    // Object.defineProperty(Object.prototype, 'b', {
    //     get: function () {
    //         return this._b;
    //     }, set: function (newVal) {
    //         this._b = newVal;
    //     }
    // })
    // a.b = 2;
    // console.log(a.b);







    // 包装对象
    // 基本数据类型（string,number,boolean）,对这些操作是没有办法的，因为无法再这些数据上进行操作
    // 为了解决这个问题，js提供了一系列的包装对象（Boolean,String,Number），这些包装对象和基本数据类型是两回事，基本数据类型的值是封装在包装对象内部的，可以直接在包装对象上调用方法
    // 通过这些包装对象的方法，可以方便对基本数据类型的数据进行操作
    // 包装对象在执行完操作后，会被销毁，因此在操作过程中是存在性能损耗的
    // 注意：虽然包装对象是对应的基本数据类型的变量，但是包装对象不是基本数据类型，是临时性的对象
    // var a = 123
    // var b = Number('123');
    // console.log(a);
    // console.log(b);
    // console.log(a === b);
    // console.log(a.toFixed(2));

    // var c = new Boolean(false);
    // console.log(c);
    // console.log(!!c);




    // // 面试题：如何让a == 1 && a == 2 && a ==3为true呢？
    // var a = {
    //     const: 1,
    //     valueOf: function () {

    //         return this.const++;
    //     }
    // }
    // console.log(a == 1 && a == 2 && a == 3);




    // 自定义方法
    // Number.prototype.triple = function (n) {
    //     return this + 10;
    // }
    // n = 5;
    // console.log(n.triple());





















































</script>

</html>